﻿// Copyright (c) : 通力凯顿（北京）系统集成有限公司
// Writer:Wangjh 
// create Date:20221026
// Rewriter:
// Rewrite Date:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using StackExchange.Redis;
using System.Configuration;
using System.Threading.Tasks;

namespace LYMesApi.Util
{
    public class RedisHelper
    {

        private static string connstr = ConfigurationManager.AppSettings["RedisClient"];
        private static ConnectionMultiplexer conn = ConnectionMultiplexer.Connect(connstr);
        private int dbNum = 1;
        private IDatabase db = conn.GetDatabase(1);

        public RedisHelper(int n = 1)
        {
            dbNum = n;
            db = conn.GetDatabase(dbNum);
        }
        /// <summary>
        /// 获取使用的数据库编号
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        public int GetDbNum()
        {
            return dbNum;
        }

        /// <summary>
        /// 获取database
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        public IDatabase GetDb()
        {
            return db;
        }


        /// <summary>
        /// 根据key设置过期时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="expiry"></param>
        /// <remarks></remarks>
        public void SetKeyExpiry(string key, TimeSpan expiry)
        {
            db.KeyExpire(key, expiry);
        }
        /// <summary>
        /// 是否存在某个key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool ExistsKey(string key)
        {
            return db.KeyExists(key);
        }
        /// <summary>
        /// 删除某个key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool DeleteKey(string key)
        {
            return db.KeyDelete(key);
        }

        /// <summary>
        /// 设置或更新key的value
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">value</param>
        /// <param name="expiry">过期时间，分钟</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public Task<bool> SetStringValueAsync(string key, string value, double expiry)
        {
            return db.StringSetAsync(key, value, TimeSpan.FromMinutes(expiry));
        }

        /// <summary>
        /// 设置或更新key的value
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">value</param>
        /// <param name="expiry">过期时间，分钟</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool SetStringValue(string key, string value, TimeSpan expiry)
        {
            return db.StringSet(key, value, expiry);
        }

        /// <summary>
        /// 设置或更新key的value
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">value</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool SetStringValue(string key, string value)
        {
            return db.StringSet(key, value);
        }

        /// <summary>
        /// 保存多个key value
        /// </summary>
        /// <param name="arr"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool SetStringValue(KeyValuePair<RedisKey, RedisValue>[] arr)
        {
            return db.StringSet(arr);
        }

        /// <summary>
        /// 获取一个key的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue GetStringByKey(string key)
        {
            return db.StringGet(key);
        }

        /// <summary>
        /// 获取多个key的值
        /// </summary>
        /// <param name="keyList"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue[] GetStringByKey(List<RedisKey> keyList)
        {
            return db.StringGet(keyList.ToArray());
        }

        /// <summary>
        /// 删除key的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool DeleteStringByKey(string key)
        {
            return db.KeyDelete(key);
        }

        /// <summary>
        /// 删除多个key的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public long DeleteStringByKey(RedisKey[] key)
        {
            return db.KeyDelete(key);
        }

        /// <summary>
        /// 为计数器数字增长val
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public double StringIncrement(string key, double val = 1)
        {
            return db.StringIncrement(key, val);
        }

        /// <summary>
        /// 为计数器数字减少val
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public double StringDecrement(string key, double val = 1)
        {
            return db.StringDecrement(key, val);
        }


        /// <summary>
        /// 设置或更新hash值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="hashKey"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool SetHashValue(string key, string hashKey, string value)
        {
            return db.HashSet(key, hashKey, value);
        }

        /// <summary>
        /// 保存一个集合
        /// </summary>
        /// <param name="key"></param>
        /// <param name="HashEntryList"></param>
        /// <remarks></remarks>
        public void SetHashValue(string key, List<HashEntry> HashEntryList)
        {
            db.HashSet(key, HashEntryList.ToArray());
        }

        /// <summary>
        /// 获取Hash中的单个key的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="hasFildValue"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue GetHashValue(string key, string hasFildValue)
        {
            return db.HashGet(key, hasFildValue);
        }

        /// <summary>
        /// 获取hash中的多个key的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="hasFildValueList"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue[] GetHashValue(string key, List<RedisValue> hasFildValueList)
        {
            return db.HashGet(key, hasFildValueList.ToArray());
        }

        /// <summary>
        /// 获取hashkey所有Redis key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue[] GetHashAllKeys(string key)
        {
            return db.HashKeys(key);
        }

        /// <summary>
        /// 获取hashkey所有Redis Value
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public HashEntry[] GetHashAllValues(string key)
        {
            return db.HashGetAll(key);
        }

        /// <summary>
        /// 删除hasekey
        /// </summary>
        /// <param name="key"></param>
        /// <param name="hasFildValue"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool DeleteHash(string key, string hasFildValue)
        {
            return db.HashDelete(key, hasFildValue);
        }

        /// <summary>
        /// 是否存在某个hash的key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="hasFildValue"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool ExistsHash(string key, string hasFildValue)
        {
            return db.HashExists(key, hasFildValue);
        }


        /// <summary>
        /// 从左侧添加list
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public long PushListLeft(string key, RedisValue val)
        {
            return db.ListLeftPush(key, val);
        }

        /// <summary>
        /// 从左侧添加多个list
        /// </summary>
        /// <param name="key"></param>
        /// <param name="vals"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public long PushListLeft(string key, RedisValue[] vals)
        {
            return db.ListLeftPush(key, vals);
        }

        /// <summary>
        /// 从右侧添加list
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public long PushListRight(string key, RedisValue val)
        {
            return db.ListRightPush(key, val);
        }

        /// <summary>
        /// 从右侧添加多个list
        /// </summary>
        /// <param name="key"></param>
        /// <param name="vals"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public long PushListRight(string key, RedisValue[] vals)
        {
            return db.ListRightPush(key, vals);
        }

        /// <summary>
        /// 从左侧取1个值，并删除
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue PopListLeft(string key)
        {
            return db.ListLeftPop(key);
        }

        /// <summary>
        /// 从右侧取1个值，并删除
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue PopListRight(string key)
        {
            return db.ListRightPop(key);
        }

        /// <summary>
        /// 获取list所有值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="s"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue[] RangeList(string key, long s = 0, long e = -1)
        {
            return db.ListRange(key, s, e);
        }

        /// <summary>
        /// 是否包含某个值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool ExistsList(string key, string value)
        {
            RedisValue[] values = db.ListRange(key);

            return values.Any(n =>
            {
                return n.ToString() == value;
            });
        }


        // 下次用再加



        /// <summary>
        /// 添加set数据，根据key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool AddSet(string key, RedisValue value)
        {
            return db.SetAdd(key, value);
        }

        /// <summary>
        /// 添加多个set数据，根据key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public long AddSet(string key, RedisValue[] value)
        {
            return db.SetAdd(key, value);
        }

        /// <summary>
        /// 求key集合的数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public long GetSetLength(string key)
        {
            return db.SetLength(key);
        }

        /// <summary>
        /// 是否包含指定值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool ExistsSet(string key, RedisValue value)
        {
            return db.SetContains(key, value);
        }

        /// <summary>
        /// 获取key中的所有值,数据类型要一致，便于存储
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue[] GetSetValues(string key)
        {
            return db.SetMembers(key);
        }


        /// <summary>
        /// 删除set数据，根据key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool RemoveSet(string key, RedisValue value)
        {
            return db.SetRemove(key, value);
        }

        /// <summary>
        /// 删除多个set数据，根据key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public long RemoveSet(string key, RedisValue[] value)
        {
            if (value == null)
                return 0;
            if (value.Length == 0)
                return 0;
            return db.SetRemove(key, value);
        }

        /// <summary>
        /// 获取多个key集合的交集
        /// </summary>
        /// <param name="keyList"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue[] IntersectSet(RedisKey[] keyList)
        {
            return db.SetCombine(SetOperation.Intersect, keyList);
        }

        /// <summary>
        /// 获取多个key集合的并集(加到一起，去重)
        /// </summary>
        /// <param name="keyList"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue[] UnionSet(RedisKey[] keyList)
        {
            return db.SetCombine(SetOperation.Union, keyList);
        }

        /// <summary>
        /// 获取多个key集合的差集(eg:h1,h2,h3,h4和h4,h5,h6两个集合的差集是h5,h6)
        /// </summary>
        /// <param name="keyList"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public RedisValue[] DifferenceSet(RedisKey[] keyList)
        {
            return db.SetCombine(SetOperation.Union, keyList);
        }


        /// <summary>
        /// 添加value和sequence，根据key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool AddSortedSet(string key, RedisValue value, double sequence)
        {
            return db.SortedSetAdd(key, value, sequence);
        }

        /// <summary>
        /// 自增，在原有score的基础上增加sequence
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="saddSequence"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public double IncrementSortedSet(string key, RedisValue value, double saddSequence)
        {
            return db.SortedSetIncrement(key, value, saddSequence);
        }

        /// <summary>
        /// 锁验证，如果存在锁key并且值是val返回true，如果不存在锁key,设置锁值为val，返回true
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <param name="exp"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool LockTake(RedisKey key, RedisValue val, TimeSpan exp)
        {
            return db.LockTake(key, val, exp);
        }
        /// <summary>
        /// 释放锁
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool LockRelease(RedisKey key, RedisValue val)
        {
            return db.LockRelease(key, val);
        }
    }
}